﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace PengSW.SqlServerTools
{
    /// <summary>
    /// 描述Sql Server数据库中数据表的基本参数
    ///     可根据表参数生成创建表的Sql语句。
    ///     可用于编辑表结构并创建表。
    /// </summary>
    public class TableParameter : INotifyPropertyChanged
    {
        #region 构造函数

        public TableParameter(string aTableName = "UnknownTable")
        {
            TableName = aTableName;
            ColumnParameters = new ColumnParameters();
        }

        #endregion

        #region 表参数

        private string m_TableName;
        public string TableName { get { return m_TableName; } set { SetValue(ref m_TableName, value, "TableName"); } }

        public ColumnParameters ColumnParameters { get; private set; }

        #endregion

        #region 生成创建表的Sql语句

        /// <summary>
        /// {0}参数为表名，{1}参数为Primary Key字段列表（字段间用逗号间隔，最后一个字段后面不能有逗号）
        /// </summary>
        private const string CreatePrimaryKeySqlTemplate =
@"
CONSTRAINT [PK_{0}] PRIMARY KEY CLUSTERED (
{1}
) ON [PRIMARY]";

        /// <summary>
        /// {0}为表名，
        /// {1}为字段列表（字段间用逗号间隔，最后一个字段后面可以有也可以没有逗号），
        /// {2}为Primary Key描述，根据CreatePrimaryKeyTemplate生成，如果没有指定Primary Key，则{2}为空
        /// </summary>
        private const string CreateTableSqlTemplate =
@"CREATE TABLE [{0}](
{1}
{2}
) ON [PRIMARY]";

        public string GetCreateTableSql()
        {
            // 生成创建字段的Sql
            StringBuilder aCreateColumnsSqlBuilder = new StringBuilder();
            foreach (ColumnParameter aColumnParameter in ColumnParameters)
            {
                aCreateColumnsSqlBuilder.AppendLine(aColumnParameter.GetCreateColumnSql());
            }
            string aCreateColumnsSql = aCreateColumnsSqlBuilder.ToString();

            // 生成创建PrimaryKey的Sql
            string aCreatePrimaryKeySql = string.Empty;
            var aPrimaryKeys = (from r in ColumnParameters where r.IsPrimaryKey select r).ToArray();
            if (aPrimaryKeys.Length > 0)
            {
                StringBuilder aCreatePrimaryKeySqlBuilder = new StringBuilder();
                for (int i = 0; i < aPrimaryKeys.Length - 1; i++)
                {
                    aCreatePrimaryKeySqlBuilder.AppendLine(string.Format("[{0}] ASC,", aPrimaryKeys[i].ColumnName));
                }
                // 最后一个字段后面没有逗号，且不需要分行（模板CreateTableSqlTemplate中{2}后面已有分行）
                aCreatePrimaryKeySqlBuilder.Append(string.Format("[{0}] ASC", aPrimaryKeys[aPrimaryKeys.Length - 1].ColumnName));

                aCreatePrimaryKeySql = string.Format(CreatePrimaryKeySqlTemplate, TableName, aCreatePrimaryKeySqlBuilder.ToString());
            }

            // 生成创建表的Sql
            return string.Format(CreateTableSqlTemplate, TableName, aCreateColumnsSql, aCreatePrimaryKeySql);
        }

        #endregion

        #region INotifyPropertyChanged实现

        private void RaisePropertyChanged(string aPropertyName)
        {
            if (PropertyChanged != null) PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(aPropertyName));
        }

        private void SetValue<T>(ref T aTarget, T aSource, string aPropertyName, params string[] aRelatedPropertyNames)
        {
            if (Object.Equals(aTarget, aSource)) return;
            aTarget = aSource;
            RaisePropertyChanged(aPropertyName);
            if (aRelatedPropertyNames != null) foreach (string aName in aRelatedPropertyNames) RaisePropertyChanged(aName);
        }

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}
